package com.gjzhao.fmmall.service;

import com.rabbitmq.client.Channel;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**
 * @Description: 消息消费方法
 * @Author: gjzhao
 * @Date Created in 2022-02-19 3:24 下午
 */
@Service
@RabbitListener(queues = "msgQueue") //指定需要监听的消息队列 todo 测试订单超时，暂时先关闭该监听
public class MessageService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @RabbitHandler //添加 @RabbitHandler 表示监听到消息后的处理逻辑
    public void handleMessage(String msg, Channel channel, Message message) { //消息就会达到message参数上面

        try {

            //一旦消息被监听到就回去进行消费
            logger.info("-----监听到消息:{}---", msg);

            //消费者进行手动应答:表示当前消费者接收到这条消息
            //参数1：获取消息对象的属性中的索性属性(每条消息到达队列后，都有一个索引值)
            //参数2：是否批量应答(一次性将小于当前消息索引的消息进行ack应答)
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

            logger.info("----消费方手动应答完成----");

        } catch (Exception e) {

            logger.error("-----当前消费者处理消息:{},发生异常:{}-----", msg, e.getMessage());
            //需要告诉队列消息消费失败，将消息重新入队列
            //参数1：索引
            //参数2：是否批量
            //参数3：是否重写加入队列
            try {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (IOException ex) {
                logger.error("-----消息异常处理发生异常---");
            }
        }
    }

}
